
package org.bridgen.lang.semantics.ast;
import java.util.*;




public class IslandDecl extends NodeDecl implements Cloneable {
    public void flushCache() {
        super.flushCache();
    }
     @SuppressWarnings({"unchecked", "cast"})  public IslandDecl clone() throws CloneNotSupportedException {
        IslandDecl node = (IslandDecl)super.clone();
        node.in$Circle(false);
        node.is$Final(false);
    return node;
    }
     @SuppressWarnings({"unchecked", "cast"})  public IslandDecl copy() {
      try {
          IslandDecl node = (IslandDecl)clone();
          if(children != null) node.children = (ASTNode[])children.clone();
          return node;
      } catch (CloneNotSupportedException e) {
      }
      System.err.println("Error: Could not clone node of type " + getClass().getName() + "!");
      return null;
    }
     @SuppressWarnings({"unchecked", "cast"})  public IslandDecl fullCopy() {
        IslandDecl res = (IslandDecl)copy();
        for(int i = 0; i < getNumChildNoTransform(); i++) {
          ASTNode node = getChildNoTransform(i);
          if(node != null) node = node.fullCopy();
          res.setChild(node, i);
        }
        return res;
    }
    // Declared in NameAnalysis.jrag at line 46



	/**
	 * Checking:
	 * 1) IslandDecl must be part of a bridge declaration
	 * 2) Each island must have a recovery declaration
	 */
	public void nameAnalysis(Collection errorList) {
		super.nameAnalysis(errorList);
		if (bridge() == null) {
			error(errorList, "Island must be part of a bridge declaration");
		}
		if (!hasRecovery()) {
	 		error(errorList, "Island " + getName() + " has no recovery");
		}
		
	}

    // Declared in PrettyPrint.jrag at line 47

    
    public void pp(StringBuffer buf) {
    	buf.append("island " + getName());
    	if (hasSuperNode()) {
    		buf.append(" : ");
    		getSuperNode().pp(buf);
    	} 
    }

    // Declared in TypeAnalysis.jrag at line 32


	/**
	 * Checking:
	 * 1) Checking type of super node - must be island
	 * 1) NodeDecl and super NodeDecl (if any) must be both start or end islands
	 */	
	public void typeAnalysis(Collection errorList) {
		super.typeAnalysis(errorList);
		
		if (hasSuperNode()) {
			NodeDecl superDecl = getSuperNode().decl();
			if (!superDecl.isIslandDecl()) {
				error(errorList, "Super node is not an island");
			} else {
				IslandDecl superIsland = (IslandDecl)superDecl;
				if (isStartIsland() && superIsland.isEndIsland()) {
					error(errorList, "Node is start island but super node is end island");
				} 
				if (isEndIsland() && superIsland.isStartIsland()) {
					error(errorList, "Node is end island but super node is start island");
				}
			}
		}
	}

    // Declared in TypeCodeGen.jrag at line 395

	
	public void generateMethods(String indent, StringBuffer buf) {
		super.generateMethods(indent, buf);
	
		// Method: boolean bridgeMatch(Island, int)
		generateMethod_bridgeMatch(indent, buf);
			
		// Method: boolean possibleConstructionSite(LexicalNode)
		generateMethod_possibleSite(indent, buf);
		
		// Method: is bridge end - 
		//   boolean isStartIsland() or 
		//   boolean isEndIsland()
		generateMethod_isBridgeEnd(indent, buf);
		
		// Method: create bridge end (only for concrete islands) - 
		//   StartIsland createStartIsland(Interval) or 
		//   EndIsland createEndIsland(Interval)
		generateMethod_createBridgeEnd(indent, buf);	
	}

    // Declared in TypeCodeGen.jrag at line 417

	
	// Code generation of bridge match method
	
	public void generateMethod_bridgeMatch(String indent, StringBuffer buf) {
		buf.append(indent + "public boolean bridgeMatch(Island island, int tol) {\n");
		
		if (isStartIsland()) {
			String endIslandName = bridge().getEnd().getName();
			buf.append(indent + INDENT + "if (isEndIsland(island)) {\n");
			buf.append(indent + INDENT + INDENT + endIslandName + 
				" end = (" + endIslandName + ")island;\n");
			buf.append(indent + INDENT + INDENT + getName() + " start = this;\n");
		} else {
			String startIslandName = bridge().getStart().getName();
			buf.append(indent + INDENT + "if (isStartIsland(island)) {\n");
			buf.append(indent + INDENT + INDENT + startIslandName + 
				" start = (" + startIslandName + ")island;\n");
			buf.append(indent + INDENT + INDENT + getName() + " end = this;\n");
		}
		if (bridge().hasWhenExpr()) {
			buf.append(indent + INDENT + INDENT + "return ");
			Expr expr = bridge().getWhenExpr();
			expr.generateAttrChecks(indent + INDENT + INDENT, buf);
			buf.append("\n" + indent + INDENT + INDENT + "(");
			expr.generateCode(indent + INDENT + INDENT, buf);
			buf.append(");\n");
		} else {
			buf.append(indent + INDENT + INDENT + "return super.bridgeMatch(island, tol);\n");
		}
		buf.append(indent + INDENT + "}\n");
		buf.append(indent + INDENT + "return false;\n");
		
		buf.append(indent + "}\n\n");
	}

    // Declared in TypeCodeGen.jrag at line 559

	

	// Code generation of possible site method
	
	public void generateMethod_possibleSite(String indent, StringBuffer buf) {
	
		// Leave recovery to a super class
		if (recovery() == null) {
			return;
		}
		
		buf.append(indent + "public boolean possibleConstructionSite(LexicalNode node) {\n");		
		recovery().generateMethod_possibleSite(indent + INDENT, buf);
		buf.append(indent + "}\n\n");
	}

    // Declared in TypeCodeGen.jrag at line 659

	
	// Code generation of is bridge end method
	
	public void generateMethod_isBridgeEnd(String indent, StringBuffer buf) {
		if (isStartIsland()) {
			buf.append(indent + "public boolean isEndIsland(LexicalNode node) {\n");
			buf.append(indent + INDENT + "return node instanceof " + bridge().getEnd().getName() + ";\n");
			buf.append(indent + "}\n");
		} else {
			buf.append(indent + "public boolean isStartIsland(LexicalNode node) {\n");
			buf.append(indent + INDENT + "return node instanceof " + bridge().getStart().getName() + ";\n");
			buf.append(indent + "}\n");		
		} 
	}

    // Declared in TypeCodeGen.jrag at line 673

	
	// Code generation of create bridge end method
	
	public void generateMethod_createBridgeEnd(String indent, StringBuffer buf) {
		if (!isAbstract()) {
			if (isStartIsland()) {
				buf.append(indent + "public EndIsland createEndIsland(Interval interval) {\n");
				String endIsland = bridge().getEnd().getName();
				buf.append(indent + INDENT + endIsland + " node = new " + endIsland + 
					"(null, interval, " + endIsland + ".VALUE);\n");
				if (forSGLR()) {
					buf.append(indent + INDENT + "node.setTokenUse(tokenNbr);\n");
				}
				buf.append(indent + INDENT + "return node;\n");
				buf.append(indent + "}\n");
			} else {
				buf.append(indent + "public StartIsland createStartIsland(Interval interval) {\n");
				String startIsland = bridge().getStart().getName();
				buf.append(indent + INDENT + startIsland + " node = new " + startIsland + 
					"(null, interval, " + startIsland + ".VALUE);\n");
				if (forSGLR()) {
					buf.append(indent + INDENT + "node.setTokenUse(tokenNbr);\n");
				}
				buf.append(indent + INDENT + "return node;\n");
				buf.append(indent + "}\n");		
			} 
		}
	}

    // Declared in bridgit.ast at line 3
    // Declared in bridgit.ast line 23

    public IslandDecl() {
        super();

        setChild(new Opt(), 0);

    }

    // Declared in bridgit.ast at line 11


    // Declared in bridgit.ast line 23
    public IslandDecl(String p0, Opt<NodeUse> p1) {
        setName(p0);
        setChild(p1, 0);
    }

    // Declared in bridgit.ast at line 16


  protected int numChildren() {
    return 1;
  }

    // Declared in bridgit.ast at line 19

  public boolean mayHaveRewrite() { return false; }

    // Declared in bridgit.ast at line 2
    // Declared in bridgit.ast line 20
    public void setName(String value) {
        tokenString_Name = value;
    }

    // Declared in bridgit.ast at line 5

    public String getName() {
        return tokenString_Name != null ? tokenString_Name : "";
    }

    // Declared in bridgit.ast at line 2
    // Declared in bridgit.ast line 20
    public void setSuperNodeOpt(Opt<NodeUse> opt) {
        setChild(opt, 0);
    }

    // Declared in bridgit.ast at line 6


    public boolean hasSuperNode() {
        return getSuperNodeOpt().getNumChild() != 0;
    }

    // Declared in bridgit.ast at line 10


     @SuppressWarnings({"unchecked", "cast"})  public NodeUse getSuperNode() {
        return (NodeUse)getSuperNodeOpt().getChild(0);
    }

    // Declared in bridgit.ast at line 14


    public void setSuperNode(NodeUse node) {
        getSuperNodeOpt().setChild(node, 0);
    }

    // Declared in bridgit.ast at line 17

     @SuppressWarnings({"unchecked", "cast"})  public Opt<NodeUse> getSuperNodeOpt() {
        return (Opt<NodeUse>)getChild(0);
    }

    // Declared in bridgit.ast at line 21


     @SuppressWarnings({"unchecked", "cast"})  public Opt<NodeUse> getSuperNodeOptNoTransform() {
        return (Opt<NodeUse>)getChildNoTransform(0);
    }

    // Declared in NameAnalysis.jrag at line 68
 @SuppressWarnings({"unchecked", "cast"})     public boolean hasRecovery() {
        boolean hasRecovery_value = hasRecovery_compute();
        return hasRecovery_value;
    }

    private boolean hasRecovery_compute() {
		if (recovery() == null) {
			if (hasSuperNode()) {
				NodeDecl superDecl = getSuperNode().decl();
				if (superDecl == null || !superDecl.isIslandDecl()) {
					return false;
				}
				return ((IslandDecl)superDecl).hasRecovery();
			}
			return false;
		}
		return true;
	}

    // Declared in NameAnalysis.jrag at line 82
 @SuppressWarnings({"unchecked", "cast"})     public RecoverDecl recovery() {
        RecoverDecl recovery_value = recovery_compute();
        return recovery_value;
    }

    private RecoverDecl recovery_compute() {  return lookupRecovery(getName());  }

    // Declared in NameAnalysis.jrag at line 141
 @SuppressWarnings({"unchecked", "cast"})     public AttrDecl lookupAttrDecl(String name) {
        AttrDecl lookupAttrDecl_String_value = lookupAttrDecl_compute(name);
        return lookupAttrDecl_String_value;
    }

    private AttrDecl lookupAttrDecl_compute(String name) {
		/*
		if (name.equals("hasBridge")) {
			return NodeDecl.ATTR_DECL_hasBridge;
		}
		*/
		return super.lookupAttrDecl(name);
	}

    // Declared in NameAnalysis.jrag at line 279
 @SuppressWarnings({"unchecked", "cast"})     public BridgeDecl bridge() {
        BridgeDecl bridge_value = bridge_compute();
        return bridge_value;
    }

    private BridgeDecl bridge_compute() {  return lookupBridge(getName());  }

    // Declared in TypeAnalysis.jrag at line 81
 @SuppressWarnings({"unchecked", "cast"})     public boolean isIslandDecl() {
        boolean isIslandDecl_value = isIslandDecl_compute();
        return isIslandDecl_value;
    }

    private boolean isIslandDecl_compute() {  return true;  }

    // Declared in TypeAnalysis.jrag at line 92
 @SuppressWarnings({"unchecked", "cast"})     public boolean isStartIsland() {
        boolean isStartIsland_value = isStartIsland_compute();
        return isStartIsland_value;
    }

    private boolean isStartIsland_compute() {  return bridge().isStart(getName());  }

    // Declared in TypeAnalysis.jrag at line 93
 @SuppressWarnings({"unchecked", "cast"})     public boolean isEndIsland() {
        boolean isEndIsland_value = isEndIsland_compute();
        return isEndIsland_value;
    }

    private boolean isEndIsland_compute() {  return bridge().isEnd(getName());  }

    // Declared in TypeAnalysis.jrag at line 101
 @SuppressWarnings({"unchecked", "cast"})     public String defaultSuperClass() {
        String defaultSuperClass_value = defaultSuperClass_compute();
        return defaultSuperClass_value;
    }

    private String defaultSuperClass_compute() {  return isStartIsland() ? "StartIsland" : "EndIsland";  }

    // Declared in NameAnalysis.jrag at line 83
 @SuppressWarnings({"unchecked", "cast"})     public RecoverDecl lookupRecovery(String name) {
        RecoverDecl lookupRecovery_String_value = getParent().Define_RecoverDecl_lookupRecovery(this, null, name);
        return lookupRecovery_String_value;
    }

    // Declared in NameAnalysis.jrag at line 280
 @SuppressWarnings({"unchecked", "cast"})     public BridgeDecl lookupBridge(String name) {
        BridgeDecl lookupBridge_String_value = getParent().Define_BridgeDecl_lookupBridge(this, null, name);
        return lookupBridge_String_value;
    }

public ASTNode rewriteTo() {
    return super.rewriteTo();
}

}
